TITLE c3_context_x64.asm

; THIS ASM FILE IS ONLY FOR X64 (amd64)

BLENGTH TEXTEQU <08h>

.DATA

;//////////////////////////////////////////////////////////////////////////////////

; x64 is just a pack of junk.

;//////////////////////////////////////////////////////////////////////////////////

.CODE

;//////////////////////////////////////////////////////////////////////////////////
; API declear
; Prevent MASM generate code like "push ebp, mov ebp, esp"

c3_restore_context PROC
	jmp _inside_restore_context;
c3_restore_context ENDP

c3_jmp_context PROC
	jmp _inside_jmp_context;
c3_jmp_context ENDP

c3_save_context PROC
	jmp _inside_save_context;
c3_save_context ENDP

c3_get_call_bp PROC
	jmp _inside_get_call_bp;
c3_get_call_bp ENDP

c3_set_jmp PROC
	jmp _inside_set_jmp;
c3_set_jmp ENDP

c3_long_jmp PROC
	jmp _inside_long_jmp;
c3_long_jmp ENDP

;//////////////////////////////////////////////////////////////////////////////////

_inside_set_jmp:

	;	RCX IS ALREADY GET ARGUMENT #1

	xor		rax,									rax;

	mov		[rcx+00h*BLENGTH],		rbx;
	mov		[rcx+01h*BLENGTH],		rdi;
	mov		[rcx+02h*BLENGTH],		rsi;
	mov		[rcx+03h*BLENGTH],		r12;
	mov		[rcx+04h*BLENGTH],		r13;
	mov		[rcx+05h*BLENGTH],		r14;
	mov		[rcx+06h*BLENGTH],		r15;
	mov		[rcx+07h*BLENGTH],		rbp;
	mov		[rcx+08h*BLENGTH],		rsp;

	mov		rdx,									[rsp];
	mov		[rcx+09h*BLENGTH],		rdx;

	ret;

;//////////////////////////////////////////////////////////////////////////////////

_inside_long_jmp:
	
	;	RCX IS ALREADY GET ARGUMENT #1
	;	RDX IS ALREADY GET ARGUMENT #2

	mov		rax,									rdx;
	mov		rbx,									[rcx+00h*BLENGTH];
	mov		rdi,									[rcx+01h*BLENGTH];
	mov		rsi,									[rcx+02h*BLENGTH];
	mov		r12,									[rcx+03h*BLENGTH];
	mov		r13,									[rcx+04h*BLENGTH];
	mov		r14,									[rcx+05h*BLENGTH];
	mov		r15,									[rcx+06h*BLENGTH];
	mov		rbp,									[rcx+07h*BLENGTH];
	mov		rsp,									[rcx+08h*BLENGTH];

	mov		rdx,									[rcx+09h*BLENGTH];

	mov		[rsp],								rdx;

	ret;

;//////////////////////////////////////////////////////////////////////////////////

_inside_restore_context:

	;	RCX IS ALREADY GET ARGUMENT #1

	mov		r10,									[rsp];

	mov		rbx,									[rcx+01h*BLENGTH];									SAVE REGISTER
	mov		rdi,									[rcx+02h*BLENGTH];
	mov		rsi,									[rcx+03h*BLENGTH];
	mov		r12,									[rcx+04h*BLENGTH];
	mov		r13,									[rcx+05h*BLENGTH];
	mov		r14,									[rcx+06h*BLENGTH];
	mov		r15,									[rcx+07h*BLENGTH];

	mov		rax,									[rcx+0ah*BLENGTH];		GET STACK SIZE
	mov		r8,									[rcx+09h*BLENGTH];		GET BP

	add		rcx,									0bh*BLENGTH;				LOAD STACK
	sub		r8,									BLENGTH;

_inside_restore_context_loop:

	and		rax,									rax;
	jz			_inside_restore_context_loop_end;

	mov		rdx,									[rcx];
	mov		[r8],									rdx;

	add		rcx,									BLENGTH;
	sub		r8,									BLENGTH;
	sub		rax,									BLENGTH;

	jmp		_inside_restore_context_loop;

_inside_restore_context_loop_end:

	mov		[rsp]	,								r10;

	ret;

;//////////////////////////////////////////////////////////////////////////////////

_inside_jmp_context:

	;	RCX IS ALREADY GET ARGUMENT #1
	mov		rdx,									[rcx+00h*BLENGTH];

	and		rdx,									rdx;
	jz			_inside_jmp_context_end;

	mov		[rsp],								rdx;
	xor		rax,									rax;
	mov		[rcx+00h*BLENGTH],		rax;									CLEAR IP PLACE

_inside_jmp_context_end:
	ret;

;//////////////////////////////////////////////////////////////////////////////////

_inside_save_context:
	
	;	RCX IS ALREADY GET ARGUMENT #1

	mov		rdx,									[rsp];								GET AND SAVE RETURN PLACE;
	mov		[rcx+00h*BLENGTH],		rdx;

	mov		[rcx+01h*BLENGTH],		rbx;									SAVE REGISTER
	mov		[rcx+02h*BLENGTH],		rdi;
	mov		[rcx+03h*BLENGTH],		rsi;
	mov		[rcx+04h*BLENGTH],		r12;
	mov		[rcx+05h*BLENGTH],		r13;
	mov		[rcx+06h*BLENGTH],		r14;
	mov		[rcx+07h*BLENGTH],		r15;

	mov		r8,									[rcx+09h*BLENGTH];		SAVE STACK SIZE
	mov		rax,									r8;									GET BP
	sub		r8,									rsp;
	mov		[rcx+0ah*BLENGTH],		r8;									SIZE: R8  BP: RAX

	add		rcx,									0bh*BLENGTH;				BEGIN SAVE STACK
	sub		rax,									BLENGTH;

_inside_save_context_loop:

	and		r8,									r8;
	jz			_inside_save_context_loop_end;

	mov		rdx,									[rax];
	mov		[rcx],									rdx;

	add		rcx,									BLENGTH;
	sub		r8,									BLENGTH;
	sub		rax,									BLENGTH;

	jmp		_inside_save_context_loop;

_inside_save_context_loop_end:

	ret;

;//////////////////////////////////////////////////////////////////////////////////

_inside_get_call_bp:
	
	mov		rax,									rsp;
	ret;

;//////////////////////////////////////////////////////////////////////////////////

END